﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Star_Wars
{
    enum Status { Menu, Game, Help, Records, PlayerPause, Pause, PlayerDead, GameOver, Exit }; // статусы игры

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        Status status = Status.Menu;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont pericles36Font;
        SpriteFont pericles14Font;
        SpriteFont pericles24Font;
        SpriteFont segoe24Font;

        Texture2D background; // фон
        Texture2D spriteSheet;
        Texture2D spaceship;
        Texture2D meteor;
        Texture2D star;
        Texture2D cursor;
        PlayerManager playerManager;
        AsteroidManager asteroidManager;
        ExplosionManager explosionManager;
        GoalManager goalManager;
        CollisionManager collisionManager;
        RecordsManager recordsManager;

        private float playerDeathDelayTime = 5f;
        private float playerDeathTimer = 0f;
        private int k = 0;

        private int playerStartingLives = 3;
        private Vector2 playerStartLocation = new Vector2(400, 400);
        private Vector2 scoreLocation = new Vector2(10, 10);
        private Vector2 levelLocation = new Vector2(10, 35);
        private Vector2 livesLocation = new Vector2(10, 60);
        private Vector2 cursorLocation = new Vector2(260, 105);

        private KeyboardState keyState;
        private KeyboardState prevKeyState;
        private bool isPlayed = false;

        public Game1(int width = 800, int height = 500)
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreferredBackBufferWidth = width; // ширина
            graphics.PreferredBackBufferHeight = height; // высота
            //graphics.IsFullScreen = true;
            //this.IsMouseVisible = true;
            //this.TargetElapsedTime = TimeSpan.FromSeconds(1.0f / 10.0f);
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            background = Content.Load<Texture2D>(@"Textures/backgroundScreen");
            spriteSheet = Content.Load<Texture2D>(@"Textures/spriteSheet");
            spaceship = Content.Load<Texture2D>(@"Textures/spaceship1");
            meteor = Content.Load<Texture2D>(@"Textures/meteor_pic");
            star = Content.Load<Texture2D>(@"Textures/star");
            cursor = Content.Load<Texture2D>(@"Textures/cursor");
            pericles36Font = Content.Load<SpriteFont>(@"Fonts\Pericles36");
            pericles14Font = Content.Load<SpriteFont>(@"Fonts\Pericles14");
            pericles24Font = Content.Load<SpriteFont>(@"Fonts\Pericles24");
            segoe24Font = Content.Load<SpriteFont>(@"Fonts\SegoeUIMono24");
            //song = Content.Load<Song>(@"Sounds\Song");
            playerManager = new PlayerManager(spaceship, new Rectangle(0, 0, 45, 40), 2, new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height));
            asteroidManager = new AsteroidManager(20, spriteSheet, new Rectangle(0, 0, 50, 50), 20, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height);
            goalManager = new GoalManager(star, new Rectangle(0, 0, 50, 46));
            explosionManager = new ExplosionManager(spriteSheet, new Rectangle(0, 100, 50, 50), 3, new Rectangle(0, 450, 2, 2));
            collisionManager = new CollisionManager(asteroidManager, playerManager, explosionManager, goalManager);
            recordsManager = new RecordsManager();
            SoundManager.Initialize(Content);
            //recordsManager.indicator = true;
        }

        protected override void UnloadContent()
        {

        }
        private void ResetGame()
        {
            playerManager.playerSprite.Location = playerStartLocation;
            playerManager.playerSprite.Rotation = 0f;
            foreach (Sprite asteroid in asteroidManager.Asteroids)
            {
                asteroid.Location = new Vector2(-500, -500);
            }
            playerManager.Destroyed = false;
        }
        protected override void Update(GameTime gameTime)
        {
            SoundManager.Update(gameTime);
            switch (status)
            {
                case Status.Menu:
                    {
                        //SoundManager.PlayMainTheme();
                        MediaPlayer.Resume();
                        prevKeyState = keyState;
                        keyState = Keyboard.GetState();
                        if (keyState.IsKeyDown(Keys.Down) && prevKeyState.IsKeyUp(Keys.Down))
                        {
                            if (k < 3) k++;
                            //prevKeyState = Key;
                        }
                        if (keyState.IsKeyDown(Keys.Up) && prevKeyState.IsKeyUp(Keys.Up))
                        {
                            if (k > 0) k--;
                        }
                        if (keyState.IsKeyDown(Keys.Enter) && prevKeyState.IsKeyUp(Keys.Enter))
                        {
                            switch (k)
                            {
                                case 0:
                                    playerManager.PlayerLives = playerStartingLives;
                                    playerManager.PlayerPoints = 0;
                                    playerManager.CountOfAchievedGoals = 0;
                                    asteroidManager.Level = 1;
                                    ResetGame();
                                    status = Status.Game;
                                    break;
                                case 1:
                                    status = Status.Records;
                                    break;
                                case 2:
                                    status = Status.Help;
                                    break;
                                case 3:
                                    status = Status.Exit;
                                    break;
                            }
                            k = 0;
                        }
                        switch (k)
                        {
                            case 0:
                                cursorLocation.Y = 105;
                                break;
                            case 1:
                                cursorLocation.Y = 165;
                                break;
                            case 2:
                                cursorLocation.Y = 225;
                                break;
                            case 3:
                                cursorLocation.Y = 285;
                                break;
                        }
                        //MediaPlayer.Play(song);
                        break;
                    }
                case Status.Game:
                    {
                        playerManager.Update(this, gameTime);
                        asteroidManager.Update(gameTime);
                        goalManager.Update(gameTime);
                        explosionManager.Update(gameTime);
                        collisionManager.CheckCollisions();

                        keyState = Keyboard.GetState();
                        if (keyState.IsKeyDown(Keys.Escape))
                        {
                            status = Status.Pause;
                        }
                        if (playerManager.Destroyed)
                        {
                            playerDeathTimer = 0f;
                            playerManager.PlayerLives--;
                            if (playerManager.PlayerLives < 0)
                            {
                                status = Status.GameOver;
                            }
                            else
                            {
                                status = Status.PlayerDead;
                            }
                        }
                        //MediaPlayer.Pause();
                        break;
                    }

                case Status.Records:
                    keyState = Keyboard.GetState();
                    if (keyState.IsKeyDown(Keys.Escape)) status = Status.Menu;
                    break;

                case Status.PlayerDead:
                    {
                        playerDeathTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                        asteroidManager.Update(gameTime);
                        explosionManager.Update(gameTime);
                        goalManager.Update(gameTime);
                        if (playerDeathTimer >= playerDeathDelayTime)
                        {
                            ResetGame();
                            status = Status.Game;
                        }
                        break;
                    }
                case Status.GameOver:
                    {
                        playerDeathTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                        asteroidManager.Update(gameTime);
                        explosionManager.Update(gameTime);
                        goalManager.Update(gameTime);
                        if (playerDeathTimer >= playerDeathDelayTime)
                        {
                            recordsManager.AddRecord(playerManager.PlayerPoints);
                            recordsManager.WriteRecords();
                            status = Status.Menu;
                        }
                        break;
                    }
                case Status.Help:
                    keyState = Keyboard.GetState();
                    if (keyState.IsKeyDown(Keys.Escape)) status = Status.Menu;
                    break;
                case Status.Pause:
                    prevKeyState = keyState;
                    keyState = Keyboard.GetState();
                    if (keyState.IsKeyDown(Keys.Down) && prevKeyState.IsKeyUp(Keys.Down))
                    {
                        if (k < 2) k++;
                        //prevKeyState = Key;
                    }
                    if (keyState.IsKeyDown(Keys.Up) && prevKeyState.IsKeyUp(Keys.Up))
                    {
                        if (k > 0) k--;
                    }
                    if (keyState.IsKeyDown(Keys.Enter) && prevKeyState.IsKeyUp(Keys.Enter))
                    {
                        switch (k)
                        {
                            case 0:
                                status = Status.Game;
                                break;
                            case 1:
                                status = Status.Menu;
                                break;
                            case 2:
                                status = Status.Exit;
                                break;
                        }
                        k = 0;
                    }
                    switch (k)
                    {
                        case 0:
                            cursorLocation.Y = 105;
                            break;
                        case 1:
                            cursorLocation.Y = 165;
                            break;
                        case 2:
                            cursorLocation.Y = 225;
                            break;
                    }
                    break;
                case Status.Exit:
                    {
                        this.Exit();
                        break;
                    }
            }
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(background, new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height), Color.White);
            if (status == Status.Menu)
            {
                spriteBatch.Draw(cursor, cursorLocation, Color.White);
                spriteBatch.DrawString(pericles36Font, "New game", new Vector2(275, 100), Color.Blue);
                spriteBatch.DrawString(pericles36Font, "Records", new Vector2(275, 160), Color.Blue);
                spriteBatch.DrawString(pericles36Font, "Help", new Vector2(275, 220), Color.Blue);
                spriteBatch.DrawString(pericles36Font, "Exit", new Vector2(275, 280), Color.Blue);
            }
            if (status == Status.Game || status == Status.PlayerDead || status == Status.GameOver)
            {
                spriteBatch.DrawString(pericles14Font, "Score: " + playerManager.PlayerPoints.ToString(), scoreLocation, Color.White);
                spriteBatch.DrawString(pericles14Font, "Level: " + asteroidManager.Level.ToString(), levelLocation, Color.White);
                if (status != Status.GameOver) spriteBatch.DrawString(pericles14Font, "Lives: " + playerManager.PlayerLives.ToString(), livesLocation, Color.White);
                playerManager.Draw(spriteBatch);
                //spriteBatch.Draw(meteor, new Rectangle(200, 200, 50, 50), Color.White);
                asteroidManager.Draw(spriteBatch);
                goalManager.Draw(spriteBatch);
                explosionManager.Draw(spriteBatch);
            }
            if (status == Status.Records)
            {
                string s = "";
                for (int i = 0; i < 10; i++)
                {
                    if (i < 9) s = " " + (i + 1).ToString() + ". " + recordsManager.Record(9 - i).ToString();
                    else s = (i + 1).ToString() + ". " + recordsManager.Record(9 - i).ToString();
                    spriteBatch.DrawString(segoe24Font, s, new Vector2(350, 50 + i*40), Color.White);
                }
            }
            if (status == Status.Help)
            {
                spriteBatch.DrawString(pericles24Font, "Collect bonuses and\n avoid collisions with asteroids.\n Control your spaceship\n by the arrows on the keyboard.\n\n\n\nPress Esc to return to menu.", new Vector2(100, 50), Color.White);
            }
            if (status == Status.Pause)
            {
                spriteBatch.Draw(cursor, cursorLocation, Color.White);
                spriteBatch.DrawString(pericles36Font, "Back", new Vector2(275, 100), Color.Blue);
                spriteBatch.DrawString(pericles36Font, "Menu", new Vector2(275, 160), Color.Blue);
                spriteBatch.DrawString(pericles36Font, "Exit", new Vector2(275, 220), Color.Blue);
            }
            if (status == Status.GameOver)
            {
                spriteBatch.DrawString(pericles14Font, "G A M E  O V E R !", new Vector2(this.Window.ClientBounds.Width / 2 - pericles14Font.MeasureString("G A M E  O V E R !").X / 2, 50), Color.White);
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
